<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // promise语法
      const p1 = new Promise((resolve, reject) => {
        resolve(1);
      });
      p1.then((res) => {
        console.log("res", res); // 1
      });
      console.log("p1", p1);

      class MyPromise {
        #PromiseState = "pending";
        #PromiseResult = undefined;
        #handlers = [];
        constructor(executor) {
          const resolve = (data) => {
            // promise的状态一旦发生改变，再也不能更改
            this.#changeState("fulfilled", data);
          };
          const reject = (reason) => {
            this.#changeState("rejected", reason);
          };
          try {
            executor(resolve, reject);
          } catch (error) {
            reject(error);
          }
        }
        #changeState(state, result) {
          if (this.#PromiseState !== "pending") return;
          this.#PromiseState = state;
          this.#PromiseResult = result;
          this.#run();
        }

        #run() {
          if (this.#PromiseState === "pending") return;
          while (this.#handlers.length) {
            const { onFulfilled, onRejected, resolvc, reject } =
              this.#handlers.shift();
            if (this.#PromiseState === "fulfilled") {
              if (typeof onFulfilled === "function") {
                onFulfilled(this.#PromiseResult);
              } else {
                resolvc(this.#PromiseResult);
              }
            } else {
              if (typeof onRejected === "function") {
                onRejected(this.#PromiseResult);
              } else {
                reject(this.#PromiseResult);
              }
            }
          }
        }

        then(onFulfilled, onRejected) {
          return new MyPromise((resolvc, reject) => {
            this.#handlers.push({
              onFulfilled,
              onRejected,
              resolvc,
              reject,
            });

            this.#run();
          });
        }
      }
      const p2 = new MyPromise((resolve, reject) => {
        setTimeout(() => {
          // resolve(1);
          reject(345);
        }, 1000);
      });
      p2.then(
        (res) => {
          console.log("promise完成", res);
        },
        null
        // (err) => {
        //   console.log("promise失败", err);
        // }
      ).then(
        (data) => {
          console.log("ok", data);
        },
        (err) => {
          console.log("err", err);
        }
      );
      p2.then(
        (res) => {
          console.log("promise2完成", res);
        },
        (err) => {
          console.log("promise2失败", err);
        }
      );
      p2.then(
        (res) => {
          console.log("promise3完成", res);
        },
        (err) => {
          console.log("promise3失败", err);
        }
      );
      p2.then(
        (res) => {
          console.log("promise4完成", res);
        },
        (err) => {
          console.log("promise4失败", err);
        }
      );
      console.log("p2", p2);
      // 浏览器的任务栈
      // 微任务 console.log(0);
      // 宏队列

    </script>
  </body>
</html>
